package com.prj.ufdm.demo.tutorial.jvm;

/**
 *  survivor空间溢出的场景
	-verbose:gc                    #输出GC日志模式 等同与 -XX:+PrintGC
	-XX:+PrintGCDetails            #输出详细GC日志模式
	-XX:+PrintTenuringDistribution #输出每次Minor GC(Minor GC:新生代 GC; Major GC/Full GC:老年代 GC)后新的存活周期的阈值
	-XX:+PrintGCTimeStamps         #输出GC的触发时间
	-XX:+PrintHeapAtGC             #在进行GC的前后打印出堆的信息
	-XX:+UseAdaptiveSizePolicy     #这个配置会在每次Minor GC之后对From和To区进行自适应分配大小
	
 * @author Administrator
 *
 */
public class GCParam {

	private static int _1M = 1024 * 1024;
	private static int minorGCIndex = 9;
	
	/**
	 * -Xms40m -Xmx40m -XX:NewRatio=3 -XX:SurvivorRatio=6  -XX:+PrintGCDetails -XX:+UseSerialGC
	 * 新生代 = 40M * 1/4 = 10240K = eden(10240K * 6/8) + from(10240K * 1/8) + to(10240K * 1/8) =  7680K + 1280K + 1280K 
	 * 老年代 = 40M * 3/4 = 30720K
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws Exception {
		// memoryObject1初始化1M
        MemoryObject mobj1 = new MemoryObject(1*_1M);
        // memoryObject1初始化2M
        MemoryObject mobj2 = new MemoryObject(2*_1M);
        
        for(int i=0;i<minorGCIndex;i++){
        	
        	/**
        	 * 当分配的内存大于 eden 区值时，会发生GC。
        	 * eden区总共7.5M， mobj1,mobj2 已经分配了3M。
        	 * 
        	 * 理论上在 minorGCIndex 为 5 的时候，已分配内存数为 7M（1+2+4），再分配会变成8M，就会超过 eden 区 7.5 M，这个时候应该会发生GC。
        	 * 经测试 minorGCIndex 为 3 的时候，就会发生GC
        	 */
            if(i == 3){
                System.out.println("当达到 "+i+" 次会发生GC");
            }
            new MemoryObject(1*_1M);
            System.out.println("新分配 1 M----："+i);
        }
        Thread.sleep(2000);
	}
	

}

class MemoryObject{
	
    private byte[] bytes;
    public MemoryObject(int objectSize){
        this.bytes = new byte[objectSize];
    }
}
